/**
 * 
 */

var markerIconNormal = '../images/gps-dot.png';
var markerIconOnSite = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png';
var animationMarkerIconOnSite = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png';
var map;
var mapMarkers;
var mapAnimationMarkers;
var mapMarkersLapseTimes;
var lastMarkerAnimate = 0;
var mapAnimationTimeout;
var animationSpeed = 10;
var minAnimationSpeed = 1;
var maxAnimationSpeed = 15;

$(document).ready(function() {
	
	loadMapsScript();
	/* activate events over map. not still used */
	//google.maps.event.addDomListener(window, 'load', initializeMap);
	
	refreshUsersList();

	// handle events
	$("#btn-refresh-users").click(function() {
		refreshUsersList();
		retrieveUser(null);
	});
	
	$("#btn-gps-data-filter").click(function() {
		var uid = $("#userid-retrieved").val();
		var initDate = $("#txt-gps-data-filter-init-date").val();
		var endDate = $("#txt-gps-data-filter-end-date").val();
		retrieveUserGpsData(uid, initDate, endDate);
	});
	
	$(document).on("click", ".user-row", function() {
		var uid = $(this).attr("id");
		retrieveUser(uid);
		retrieveUserGpsData(uid);
	});
	
	$(document).on("mouseenter", ".user-gps-data-row", function() {
		hideAllMapOnSiteMarkers();
		showMapOnSiteMarker($(this).attr("gps-point"));
	});
	
	$(document).on("mouseleave", ".user-gps-data-row", function() {
		hideMapOnSiteMarker($(this).attr("gps-point"));
	});
	
	$("#btn-play-map-animation").click(function() {
		if(mapAnimationTimeout != undefined) {
			alert("La animación ya se está ejecutando");
		} else {
			hideAllMapOnSiteMarkers();
			playMapAnimation();			
		}
	});
	
	$("#btn-pause-map-animation").click(function() {
		pauseMapAnimation();			
	});
	
	$("#btn-stop-map-animation").click(function() {
		stopMapAnimation();			
	});
	
	$("#btn-minus-speed-map-animation").click(function() {
		minusSpeedMapAnimation();
	});
	
	$("#btn-plus-speed-map-animation").click(function() {
		plusSpeedMapAnimation();
	});
	
	updateAnimationSpeedLabel();
	updateAnimationSpeedButtonsTitle();
});

function refreshUsersList() {
	$.ajax({
		url: '../rest/admin/users/all',
		type: 'GET',
		contentType: "application/json",
		cache: 'false',
		success: function(data) {
			if(processResponseErrors(data)) {
				paintUsersList(data.users);
			}
		}
	});
	
	var userIdRetrieved = $("#userid-retrieved").val();
	if(userIdRetrieved != "") {
		retrieveUser(userIdRetrieved);
	}
}

function paintUsersList(data) {
	$('#div-users-list').html('Actualizando usuarios');
	if(data == null || data.length == 0) {
		$('#div-users-list').html('No hay usuarios');
	} else {
		$('#div-users-list').html('');
		for ( var i in data) {
			var o = data[i];
			
			var imgUserConnectionStatus = 'red-light.png';
			var titleUserConnectionStatus = "NO CONECTADO";
			
			if(o.connected) {
				imgUserConnectionStatus = 'green-light.png';
				titleUserConnectionStatus = "CONECTADO";
			}
			
			var userRow = '<div id="' + o.id + '" class="user-row">';
			userRow += '<span class="user-connection-status">';
			userRow += '<img src="../images/' + imgUserConnectionStatus + '" title="' + titleUserConnectionStatus + '">';
			userRow += '</span>';
			userRow += o.firstName + ' ' + o.lastName + ' (' + o.userName + ')';
			
			userRow += '</div>';
			$('#div-users-list').append(userRow);
		}
	}
}

function retrieveUser(uid) {
	if(uid != null) {
		$.ajax({
			url: "../rest/admin/users/" + uid,
			type: "GET",
			contentType: "application/json",
			cache: "false",
			success: function(data) {
				if(processResponseErrors(data)) {
					paintUserData(data.user);
				}
			}
		});
	}
}

function retrieveUserGpsData(uid, initDate, endDate) {
	var initD = "";
	if(initDate != null) {
		initD = $.stringToDate(initDate);
	}
	
	var endD = "";
	if(endDate != null) {
		endD = $.stringToDate(endDate);
	}
	
	if(uid != null) {
		$.ajax({
			url: "../rest/admin/gps",
			type: "POST",
		    contentType: "application/json",
		    dataType: "json",
		    data: JSON.stringify({
			    	"userId": uid,
			    	"initDate": initD,
			    	"endDate": endD
		    		}
		    	),
			success: function(data) {
				paintUserGpsData(data);
				paintGpsDataMap(data.gpsData);
			}
		});
	}
}

function paintUserData(user) {
	
	$('#div-user-data').html('Seleccione un usuario para ver su configuración');
	
	if(user != null) {
	
		$("#userid-retrieved").val(user.id);
		
		var s = '';
		
		s += '<div class="user-data-row">';
		s += '<span class="lbl-user-data-field-name">Usuario</span>';
		s += '<span class="lbl-field-value">'+ user.userName + ' (uid=' + user.id + ')' +'</span>';
		s += '</div>';
		
		s += '<div class="user-data-row">';
		s += '<span class="lbl-user-data-field-name">Nombre</span>';
		s += '<span class="lbl-field-value">'+ user.firstName + ' ' + user.lastName +'</span>';
		s += '</div>';
		
		s += '<div class="user-data-row">';
		s += '<span class="lbl-user-data-field-name">E-mail</span>';
		s += '<span class="lbl-field-value">'+ user.email +'</span>';
		s += '</div>';
		
		var vt = "";
		if(user.vehicleType == "SPORT") {
			vt = "Deportivo";
		} else if(user.vehicleType == "STANDARD") {
			vt = "Estándar";
		} else if(user.vehicleType == "SUV") {
			vt = "Todo terreno";
		} else if(user.vehicleType == "MOTO") {
			vt = "Motocicleta";
		} else if(user.vehicleType == "SCOOTER") {
			vt = "Scooter";
		}
		s += '<div class="user-data-row">';
		s += '<span class="lbl-user-data-field-name">Tipo de vehículo</span>';
		s += '<span class="lbl-field-value">'+ vt +'</span>';
		s += '</div>';
		
		s += '<div class="user-data-row">';
		s += '<span class="lbl-user-data-field-name">Envío GPS (ms)</span>';
		s += '<span class="lbl-field-value">'+ user.fetchGpsLapseTime +'</span>';
		s += '</div>';
		
		s += '<div class="user-data-row">';
		s += '<span class="lbl-user-data-field-name">Conectado</span>';
		var connected = 'NO';
		if(user.connected) {
			connected = 'SI'; 
		}
		s += '<span class="lbl-field-value">'+ connected +'</span>';
		s += '</div>';
		
		$('#div-user-data').html(s);
	}
}

function paintUserGpsData(data) {
	if(data.filter.initDate != null) {
		$('#txt-gps-data-filter-init-date').val($.formatDate(new Date(data.filter.initDate)));
	} else {
		$('#txt-gps-data-filter-init-date').val("");
	}
	
	if(data.filter.endDate != null) {
		$('#txt-gps-data-filter-end-date').val($.formatDate(new Date(data.filter.endDate)));
	} else {
		$('#txt-gps-data-filter-end-date').val("");
	}
	
	if(data.gpsData != null && data.gpsData.length > 0) {
		$('#div-user-gps-data').html(buildGpsDataList(data.gpsData));
		showMapAnimationControls();
	} else {
		$('#div-user-gps-data').html('No se han encontrado datos GPS');
		hideMapAnimationControls();
	}
}

function buildGpsDataList(gpsData) {
	var s = '';
	
	for (var i in gpsData) {
		var o = gpsData[i];
		var ft = $.formatDateTime(new Date(o.fetchTime), true, true);
		
		s += '<div class="user-gps-data-row" gps-point="' + i + '">';
		s += ft;
		s += '<br>';
		s += '&nbsp;&nbsp;[' + o.lat + ' / ' + o.lon + ']';
		if(o.speedFromPrevious != undefined) {
			s += ' - ' + (new Number(o.distanceFromPrevious)).toFixed(3) + ' m';
			s += ' - ' + (new Number(o.speedFromPrevious)).toFixed(1) + ' km/h';
		}
		s += '</div>';
	}
	
	return s;
}

function paintGpsDataMap(data) {
	initializeMap();
	
	var hl = null;
	var hr = null;
	var vt = null;
	var vb = null;
	
	var lastPos;
	var diff;
	
	for (var i in data) {
		var o = data[i];
		
		//extract marker limits for zooming the map
		if(hl == null) {
			hl = o.lat;
		} else if(hl > o.lat) {
			hl = o.lat;
		}
		
		if(hr == null) {
			hr = o.lat;
		} else if(hr < o.lat) {
			hr = o.lat;
		}
		
		if(vt == null) {
			vt = o.lon;
		} else if(vt < o.lon) {
			vt = o.lon;
		}
		
		if(vb == null) {
			vb = o.lon;
		} else if(vb > o.lon) {
			vb = o.lon;
		}
		
		var marker = new google.maps.Marker({
						position: new google.maps.LatLng(o.lat, o.lon),
						icon: markerIconNormal,
						map: map });
		mapMarkers.push(marker);
		
		var animationMarker = new google.maps.Marker({
			position: new google.maps.LatLng(o.lat, o.lon),
			icon: markerIconNormal,
			map: map });
		mapAnimationMarkers.push(animationMarker);
		
		if(i == 0) {
			lastPos = o;
			mapMarkersLapseTimes.push(0);
		} else {
			diff = o.fetchTime - lastPos.fetchTime;
			lastPos = o;
			mapMarkersLapseTimes.push(diff);
		}
	}
	
	if(data != null && data.length > 0) {
		showMapOnSiteMarker(0);
		map.fitBounds(new google.maps.LatLngBounds(
				new google.maps.LatLng(hl, vb), 
				new google.maps.LatLng(hr, vt))
			);
	}
}

function showMapOnSiteMarker(markerIndex) {
	mapMarkers[markerIndex].setIcon(markerIconOnSite);
}

function hideMapOnSiteMarker(markerIndex) {
	mapMarkers[markerIndex].setIcon(markerIconNormal);
}

function hideAllMapOnSiteMarkers() {
	for(var i in mapMarkers) {
		hideMapOnSiteMarker(i);
	}
}

function showMapOnSiteAnimationMarker(markerIndex) {
	mapAnimationMarkers[markerIndex].setIcon(animationMarkerIconOnSite);
}

function hideMapOnSiteAnimationMarker(markerIndex) {
	mapAnimationMarkers[markerIndex].setIcon(markerIconNormal);
}

function hideAllMapOnSiteAnimationMarkers() {
	for(var i in mapAnimationMarkers) {
		hideMapOnSiteAnimationMarker(i);
	}
}

function showMapAnimationControls() {
	$("#map-animation-controls").show();
	$("#btn-pause-map-animation").hide();
}

function hideMapAnimationControls() {
	$("#map-animation-controls").hide();
}

function playMapAnimation() {
	if(lastMarkerAnimate < mapMarkers.length) {
		if(lastMarkerAnimate > 0) {
			hideMapOnSiteAnimationMarker(lastMarkerAnimate - 1);
		}
		showMapOnSiteAnimationMarker(lastMarkerAnimate++);
		mapAnimationTimeout = setTimeout(playMapAnimation, mapMarkersLapseTimes[lastMarkerAnimate] / animationSpeed);
		
		$("#btn-play-map-animation").hide();
		$("#btn-pause-map-animation").show();
	} else {
		clearInterval(mapAnimationTimeout);
		mapAnimationTimeout = undefined;
		lastMarkerAnimate = 0;
		
		$("#btn-pause-map-animation").hide();
		$("#btn-play-map-animation").show();
	}
}

function pauseMapAnimation() {
	clearInterval(mapAnimationTimeout);
	mapAnimationTimeout = undefined;
	
	$("#btn-pause-map-animation").hide();
	$("#btn-play-map-animation").show();
}

function stopMapAnimation() {
	clearInterval(mapAnimationTimeout);
	mapAnimationTimeout = undefined;
	hideAllMapOnSiteAnimationMarkers();
	lastMarkerAnimate = 0;
	showMapOnSiteAnimationMarker(0);
	
	$("#btn-pause-map-animation").hide();
	$("#btn-play-map-animation").show();
}

function minusSpeedMapAnimation() {
	if(animationSpeed > minAnimationSpeed) {
		animationSpeed--;
		updateAnimationSpeedLabel();
	}
}

function plusSpeedMapAnimation() {
	if(animationSpeed < maxAnimationSpeed) {
		animationSpeed++;
		updateAnimationSpeedLabel();
	}
}

function updateAnimationSpeedLabel() {
	$("#animation-speed-container").html('velocidad x' + animationSpeed);
}

function updateAnimationSpeedButtonsTitle() {
	$("#btn-minus-speed-map-animation").prop('title', 'Disminuir velocidad (mínima = ' + minAnimationSpeed + ')');
	$("#btn-plus-speed-map-animation").prop('title', 'Aumentar velocidad (máxima = ' + maxAnimationSpeed + ')');
}

function initializeMap() {
	mapMarkers = [];
	mapAnimationMarkers = [];
	mapMarkersLapseTimes = [];
	
	var mapOptions = {
		center : new google.maps.LatLng(0, 0),
		disableDefaultUI: true,
		zoom : 1,
		mapTypeId : google.maps.MapTypeId.ROADMAP
	};
	
	map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}

function loadMapsScript() {
	//var apiKey = "AIzaSyAwI031esGuoPxJrCp4aKCrgdveca4ZRRo";
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initializeMap";
	//script.src = "http://maps.googleapis.com/maps/api/js?key="+apiKey+"&sensor=false&callback=initialize";
	document.body.appendChild(script);
}

function processResponseErrors(response) {
	var successful = response.responseSuccessful; 
	if(!successful) {
		//TODO paint user session errors
		alert(response.responseErrors);
	}
	return successful;
}